<template>
  <span class="crud-date" :title="fullDateText">
    {{ displayText }}
  </span>
</template>

<script setup lang="ts">
import { computed } from 'vue'

/**
 * 组件属性接口
 */
interface Props {
  /** 日期值 */
  value?: string | number | Date
  /** 日期格式 */
  format?: string
  /** 是否显示相对时间 */
  relative?: boolean
  /** 空值时显示的文本 */
  emptyText?: string
}

/**
 * Props 定义
 */
const props = withDefaults(defineProps<Props>(), {
  format: 'YYYY-MM-DD',
  relative: false,
  emptyText: '-'
})

/**
 * 格式化日期
 * @param date - 日期对象
 * @param format - 格式字符串
 * @returns 格式化后的日期字符串
 */
const formatDate = (date: Date, format: string): string => {
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')

  return format
    .replace(/YYYY/g, String(year))
    .replace(/MM/g, month)
    .replace(/DD/g, day)
    .replace(/HH/g, hours)
    .replace(/mm/g, minutes)
    .replace(/ss/g, seconds)
}

/**
 * 获取相对时间
 * @param date - 日期对象
 * @returns 相对时间字符串
 */
const getRelativeTime = (date: Date): string => {
  const now = new Date()
  const diff = now.getTime() - date.getTime()
  const seconds = Math.floor(diff / 1000)
  const minutes = Math.floor(seconds / 60)
  const hours = Math.floor(minutes / 60)
  const days = Math.floor(hours / 24)
  const months = Math.floor(days / 30)
  const years = Math.floor(days / 365)

  if (years > 0) {
    return `${years}年前`
  } else if (months > 0) {
    return `${months}个月前`
  } else if (days > 0) {
    return `${days}天前`
  } else if (hours > 0) {
    return `${hours}小时前`
  } else if (minutes > 0) {
    return `${minutes}分钟前`
  } else if (seconds > 0) {
    return `${seconds}秒前`
  } else {
    return '刚刚'
  }
}

/**
 * 解析日期值
 */
const parsedDate = computed(() => {
  if (!props.value) return null

  if (props.value instanceof Date) {
    return props.value
  }

  if (typeof props.value === 'number') {
    return new Date(props.value)
  }

  if (typeof props.value === 'string') {
    // 处理常见的日期字符串格式
    const date = new Date(props.value)
    return isNaN(date.getTime()) ? null : date
  }

  return null
})

/**
 * 完整日期文本（用于 title 属性）
 */
const fullDateText = computed(() => {
  if (!parsedDate.value) return props.emptyText
  return formatDate(parsedDate.value, 'YYYY-MM-DD HH:mm:ss')
})

/**
 * 显示文本
 */
const displayText = computed(() => {
  if (!parsedDate.value) return props.emptyText

  if (props.relative) {
    return getRelativeTime(parsedDate.value)
  }

  return formatDate(parsedDate.value, props.format)
})
</script>

<style lang="scss" scoped>
.crud-date {
  color: #606266;
  font-size: 14px;
  cursor: default;

  &:hover {
    color: #409eff;
  }
}
</style>
